<?php
/**
 * Created by IntelliJ IDEA.
 * User: XD
 * Date: 2017/8/23
 * Time: 14:02
 */
namespace app\mysql\app\base;
class BaseMysql
{
    private $conn;
    private static $mode;     // 记录句柄采用的模式

    private static $_instance = null;

    static function getInstance($_builder,$mode){
        if(self::$mode != null && self::$mode === $mode){
            if(is_null(self::$_instance) || isset(self::$_instance)){
                self::$_instance = new self($_builder,$mode);
            }
            return self::$_instance;
        }else{
            self::$_instance = new self($_builder,$mode);
            return self::$_instance;
        }

    }

    static function getStatic($_builder,$mode){
        if(self::$mode != null && self::$mode === $mode) {
            if (is_null(self::$_instance) || isset(self::$_instance)) {
                self::$_instance = new static($_builder, $mode);
            }
            return self::$_instance;
        }else{
            self::$_instance = new static($_builder,$mode);
        }
    }
    /**
     * @return mixed
     */
    public function getConn()
    {
        return $this->conn;
    }

    /**
     * @param mixed $conn
     */
    public function setConn($conn)
    {
        $this->conn = $conn;
    }


    /**
     * @return int
     */
    public static function getMode()
    {
        return self::$mode;
    }

    /**
     * @param int $mode
     */
    public static function setMode($mode)
    {
        self::$mode = $mode;
    }

    //私有构造函数，防止外界实例化对象
    private function __construct($_builder,$mode)  //$servername,$username,$password
    {
        if($mode === 1){
            $this ->concatenonMysqliProcess($_builder);
            self::$mode = 1;
        }
        else if($mode === 2){
            $this -> concatenonMysqliObject($_builder);
            self::$mode = 2;
        }
        else if($mode === 3){
            $this->concatenonMysqlPDO($_builder);
            self::$mode = 3;
        }else{
            die("设置的链接模式没有匹配到，请检查输入的链接模式是否是1，2，3 的整数");
        }
        //echo "连接远程数据库成功"."<br>";
        \app\log\UseLog::addInfoAtLog('连接远程数据库成功',__FILE__,__LINE__);
    }

    //私有克隆函数，防止外办克隆对象
    private function __clone()
    {
        // TODO: Implement __clone() method.
    }



    function concatenonMysqliObject($_builder){
        $this->conn = new mysqli($_builder->getServername(),$_builder->getUsername(),$_builder->getPassword(),null,$_builder->getPort(),$_builder->getSocket());

        if($this->conn->connect_error){
            //die() 函数输出一条消息，并退出当前脚本。
            //该函数是 exit() 函数的别名。
            \app\log\UseLog::addInfoAtLog("连接mysql失败：".$this->conn->connect_error,__FILE__,__LINE__);
            die("连接mysql失败：".$this->conn->connect_error);

        }else{
            // 链接mysql成功
//            echo "链接 concatenonMysqliObject 成功";
            \app\log\UseLog::addInfoAtLog('链接 concatenonMysqliObject 成功',__FILE__,__LINE__);
        }
    }

    // 面向对象 选择数据库
    function selectDBMysqliObject($db_name){
        $this->conn->select_db($db_name);
    }

    function closeMysqliObject(){
        //实例 (MySQLi - 面向对象)
        $this->conn->close();

    }


    // 面向过程
    function concatenonMysqliProcess($_builder){
        $this->conn = mysqli_connect($_builder->getServername(),$_builder->getUsername(),$_builder->getPassword(),null,$_builder->getPort(),$_builder->getSocket());
        if(!$this->conn){
            //die() 函数输出一条消息，并退出当前脚本。
            //该函数是 exit() 函数的别名。
            \app\log\UseLog::addInfoAtLog('链接 concatenonMysqliProcess 失败',__FILE__,__LINE__);
            die("连接mysql失败：".mysqli_connect_error());
        }else{
            // 链接mysql成功
            \app\log\UseLog::addInfoAtLog('链接 concatenonMysqliProcess 成功',__FILE__,__LINE__);
        }
    }

    // 面向过程
    function selectDBMysqliProcess($conn,$db_name){
        if($conn == null || $db_name == null){
            \app\log\UseLog::addInfoAtLog('Conn 或者 db_name中有一个为null',__FILE__,__LINE__);
        }
        $result = mysqli_select_db($conn,$db_name);
        if(!$result){
            \app\log\UseLog::addInfoAtLog('selectDBMysqliProcess 选择数据库'.$db_name.'失败,根据经验，数据库名错误。result:'.$result,__FILE__,__LINE__);
            die("选择数据库失败");
        }else{
            \app\log\UseLog::addInfoAtLog('selectDBMysqliProcess 选择数据库success',__FILE__,__LINE__);
        }
    }

    public function close(){
        if(self::getMode() === 1){
            $this->closeMysqliProcess();
        }else if (self::getMode() === 2){
            $this->closeMysqliObject();
        }else if(self::getMode() == 3){
            $this->closeMysqlPDO();
        }else{
            \app\log\UseLog::addInfoAtLog('设置的链接模式没有匹配到，请检查输入的链接模式是否是1，2，3 的整数',__FILE__,__LINE__);
            die("设置的链接模式没有匹配到，请检查输入的链接模式是否是1，2，3 的整数");
        }
        \app\log\UseLog::addInfoAtLog('数据库关闭成功',__FILE__,__LINE__);
    }

    private function closeMysqliProcess(){
        //实例 (MySQLi - 面向过程)
        mysqli_close($this->conn);

    }

    // PDO
    private function concatenonMysqlPDO($_builder){
        try {
            $dsn="mysql:dbname=".$_builder->getDb().";host=".$_builder->getServername();
            $this->conn  = new PDO($dsn, $_builder->getUsername(),$_builder->getPassword(),$_builder->getOptions());
            //直接catch了
            //            // 处理连接错误
//            if ($this->conn->errorCode()) {
//                die("连接失败: " . $this->conn->errorInfo());
//            }
            // 设置 PDO 错误模式为异常
            $this->conn ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            \app\log\UseLog::addInfoAtLog('concatenonMysqlPDO 连接成功',__FILE__,__LINE__);
        }
        catch(PDOException $e)
        {
            \app\log\UseLog::addInfoAtLog('concatenonMysqlPDO 连接失败'.$e->getMessage(),__FILE__,__LINE__);
            die("");
        }
    }

    private function closeMysqlPDO(){
        //实例 (PDO)
        $this->conn = null;
        \app\log\UseLog::addInfoAtLog("closeMysqlPDO success",__FILE__,__LINE__);
    }
}